package com.zzx.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzx.common.exception.ServiceException;
import com.zzx.entity.TMenu;
import com.zzx.mapper.TMenuMapper;
import com.zzx.service.TMenuService;
import com.zzx.utils.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author CD
 * @description 针对表【t_menu】的数据库操作Service实现
 * @createDate 2024-12-04 15:06:08
 */
@Service
public class TMenuServiceImpl extends ServiceImpl<TMenuMapper, TMenu>
        implements TMenuService {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(TMenu param) {
        LambdaQueryWrapper<TMenu> wrapper = new LambdaQueryWrapper<>(TMenu.class);
        // 多租户拦截器会自动添加 company_id 条件
        wrapper.eq(TMenu::getMenuName, param.getMenuName());
        if (ObjectUtils.isEmpty(param.getMenuId())) {
            param.setMenuId(IdUtil.getSnowflakeNextId());
            param.setIsLast(0);
            if (!ObjectUtils.isEmpty(param.getParentId()) && !param.getParentId().equals("0")) {
                this.saveOrUpdate(TMenu.builder()
                        .menuId(param.getParentId())
                        .isLast(1)
                        .build());
            }
            if (ObjectUtils.isEmpty(param.getParentId())) {
                param.setParentId(0L);
            }
        } else {
            wrapper.ne(TMenu::getMenuId, param.getMenuId());
            EntityUtils.mergeNonNullProperties(this.getBaseMapper().selectById(param.getMenuId()), param);
        }
        List<TMenu> tMenuList = this.getBaseMapper().selectList(wrapper);
        if (!tMenuList.isEmpty()) {
            throw new ServiceException("菜单名称已存在");
        }
        this.saveOrUpdate(param);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(TMenu param) {

        TMenu tmenu = this.getBaseMapper().selectById(param.getMenuId());
        if (tmenu.getIsLast() != 0) {
            throw new ServiceException("不能删除非末级菜单");
        }
        if (ObjectUtils.isEmpty(this.getBaseMapper().selectList(new LambdaQueryWrapper<>(TMenu.class).eq(TMenu::getMenuId, tmenu.getParentId())))) {
            this.saveOrUpdate(TMenu.builder()
                    .menuId(tmenu.getParentId())
                    .isLast(0)
                    .build());
        }
        this.removeById(param.getMenuId());
    }

    @Override
    public List selectBy(TMenu param) {
        LambdaQueryWrapper<TMenu> wrapper = new LambdaQueryWrapper<>(TMenu.class);
        if (!ObjectUtils.isEmpty(param.getMenuName())) {
            wrapper.like(TMenu::getMenuName, param.getMenuName());
        }
        if (!ObjectUtils.isEmpty(param.getMenuCode())) {
            wrapper.like(TMenu::getMenuCode, param.getMenuCode());
        }
        if (!ObjectUtils.isEmpty(param.getMenuId())) {
            wrapper.eq(TMenu::getMenuId, param.getMenuId());
        }
        // 多租户拦截器会自动添加 company_id 条件
        List<TMenu> tMenus = this.getBaseMapper().selectList(wrapper);
        return this.generateTree(tMenus);
    }

    private List<Tree<String>> generateTree(List<TMenu> dataList) {
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        List<Tree<String>> treeNodes = TreeUtil.build(dataList, "0", treeNodeConfig,
                (data, tree) -> {
                    tree.setId(String.valueOf(data.getMenuId()));
                    tree.setParentId(String.valueOf(data.getParentId()));
                    tree.setName(data.getMenuName());
                    // 扩展属性 ...
                    tree.putExtra("menuCode", data.getMenuCode());
                    tree.putExtra("menuIcon", data.getMenuIcon());
                    tree.putExtra("isShow", data.getIsShow());
                    tree.putExtra("isLast", data.getIsLast());
                });
        return treeNodes;
    }
}




